package com.share.tool;

import com.share.bean.*;
import com.share.constant.StatusEnum;
import org.junit.Test;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * author:caifan
 * date:2019/11/17
 */
public class CreateTableSql {

    private final String STR_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    @Test
    public void test() {
        getClassName();
    }

    public void getClassName() {
        List<Field> fieldList = getFields(BdCountryzone.class);
        System.out.println(createDDLSQL(fieldList, "BdCountryzone"));
    }

    public String createDDLSQL(List<Field> fieldList, String tableName) {
        Map<String, String> typeMap = typeRelation();
        StringBuffer sqlBuffer = new StringBuffer("create table ").append(upperReplace(tableName)).append("(\n");
        fieldList.stream().forEach(field -> {
            sqlBuffer.append("`").append(upperReplace(field.getName())).append("` ").append(typeMap.get(field.getType().getSimpleName())).append(",\n");
        });
        sqlBuffer.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        return sqlBuffer.toString();
    }

    public List<Field> getFields(Class<?> tClass) {
        List<Field> fieldList = new ArrayList<>();
        Field[] declaredFields;
        while (!Objects.equals(tClass.getSimpleName(), Object.class.getSimpleName())) {
            declaredFields = tClass.getDeclaredFields();
            fieldList.addAll(Arrays.asList(declaredFields));
            tClass = tClass.getSuperclass();
        }
        return fieldList;
    }

    private String upperReplace(String name) {
        String[] chars = name.split("");
        for (int i=0;i<chars.length;i++) {
            if (STR_CHAR.contains(chars[i])) {
                if (i > 0) {
                    chars[i] = "_" + chars[i].toLowerCase();
                } else {
                    chars[i] = chars[i].toLowerCase();
                }
            }
        }
        return Arrays.stream(chars).collect(Collectors.joining());
    }


    public Map<String, String> typeRelation() {
        Map<String, String> map = new HashMap<>();
        map.put("String", "varchar(101)");
        map.put("Date", "datetime(3)");
        map.put("Long", "bigint(20)");
        map.put("Character", "char(4)");
        map.put("Integer", "int");
        map.put("BigDecimal", "decimal(20,8)");
        return map;
    }

    @Test
    public void alterSqlTest() {
        generateAlterSql();
    }

    public void generateAlterSql() {
        Map<String, String> typeMap = typeMap();
        StringBuffer sql = new StringBuffer();
        String[] tableNames = {"meta_delivery_order_line", "meta_instock_bill_line", "meta_payment_order_line", "meta_purchase_invoice_line", "meta_purchase_order_line",
                        "meta_purchase_request_line", "meta_purchasein_bill_line", "meta_receive_order_line", "meta_saleout_bill_line",
                        "meta_sales_invoice_line", "meta_sales_order_line", "meta_transfer_note_line"};
        String[] fieldNames = {"source_bill_ref_id", "upstream_bill_ref_id", "source_line_id", "upstream_line_id", "source_line_entry", "upstream_line_entry"};
        for (String table : tableNames) {
            for (String field : fieldNames) {
                sql.append("alter table ").append(table).append(" add column ").append(field).append(" ").append(typeMap.get(field)).append(";\n");
            }
        }
        System.out.println(sql.toString());

    }

    public Map<String, String> typeMap() {
        Map<String, String> typeMap = new HashMap<>();
        typeMap.put("source_bill_ref_id", "varchar(63)");
        typeMap.put("upstream_bill_ref_id", "varchar(63)");
        typeMap.put("source_line_id", "bigint(20)");
        typeMap.put("upstream_line_id", "bigint(20)");
        typeMap.put("source_line_entry", "varchar(255)");
        typeMap.put("upstream_line_entry", "varchar(255)");
        return typeMap;
    }

    @Test
    public void enumTest() {
        StatusEnum[] values = StatusEnum.values();
        for (StatusEnum status : values) {
            if (status.getCode().equals("1000")) {
                System.out.println(status.getDesc());
                return;
            }
        }
    }

    @Test
    public void filesTest() throws Exception {
        Files.readAllLines(Paths.get("D:/config/schema.properties")).stream().forEach(line -> {
            System.out.println(line);
        });
    }
}
